package redis

import (
	"context"
	"encoding/json"
	"fmt"
	"shadow/store/redis/base"
)

var PubSub = &pubSub{}

type pubSub struct {
	topics      []interface{}
	callbackMap map[string]base.HandlerFunc
}

// Start 启动
func (p *pubSub) Start() (err error) {
	return base.GetClient().Consumer(context.Background(), p.topics, p.callbackMap)
}

func (p *pubSub) Stop() (err error) {
	return nil
}

// Subscribe 订阅消息
func (p *pubSub) Subscribe(topic string, callback base.HandlerFunc) (err error) {
	if callback == nil {
		return fmt.Errorf("callback is nil")
	}

	if p.callbackMap == nil {
		p.callbackMap = make(map[string]base.HandlerFunc)
	}

	// add topic
	p.topics = append(p.topics, topic)

	// add callback
	p.callbackMap[topic] = callback
	return
}

// Publish 发布消息
func (p *pubSub) Publish(topic string, data interface{}) (err error) {
	if data == nil {
		return fmt.Errorf("data is nil")
	}

	// marshal data
	bytes, err := json.Marshal(data)
	if err != nil {
		return err
	}

	// publish message
	bSuccess := base.GetClient().Publish(context.Background(), topic, bytes)
	if !bSuccess {
		return fmt.Errorf("publish failed")
	}
	return nil
}
